package com.infoholdcity.common.controller;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infoholdcity.common.common.Result;
import com.infoholdcity.common.common.model.DictModel;
import com.infoholdcity.common.entity.SysAdvancedQueryComponent;
import com.infoholdcity.common.service.ISysDictService;
import com.infoholdcity.common.service.SysAdvancedQueryComponentService;
import com.infoholdcity.common.util.QueryGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.*;

/**
 * <p>
 * 高级查询组件表 前端控制器
 * </p>
 *
 * @author jinshihui
 * @since 2025-02-18
 */
@RestController
@RequestMapping("/advancedQueryComponent")
@Slf4j
public class SysAdvancedQueryComponentController {

    @Autowired
    private SysAdvancedQueryComponentService sysAdvancedQueryComponentService;

    @Autowired
    private ISysDictService sysDictService;

    private final DataSource dataSource;


    public SysAdvancedQueryComponentController(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 获取表字段
     *
     * @param tableName
     * @return Result
     */
    private static final List<String> FILTER_FIELDS = Arrays.asList("id", "create_time", "creator", "update_time", "updator");

    /**
     * 数据库类型到前端类型的映射
     */
    private String mapDbTypeToFieldType(String dbType) {
        switch (dbType) {
            case "VARCHAR": return "string";
            case "INT":
            case "int4": return "number";
            case "DATETIME":
            case "timestamp": return "datetime";
            case "date":
            case "DATE": return "date";
            default: return "string";
        }
    }

    /**
     * 获取查询字段
     * @param tableName
     * @return Result<Object>
     */
    @GetMapping("/fields")
    public Result<Object> getTableFields(@RequestParam String tableName) {
        try {
            log.info("获取表字段, tableName: {}", tableName);
            List<Map<String, Object>> fields = fetchTableFields(tableName);
            return Result.ok(fields);
        } catch (Exception e) {
            log.error("获取表字段失败, tableName: {}", tableName, e);
            return Result.error("获取表字段失败");
        }
    }

    private List<Map<String, Object>> fetchTableFields(String tableName) throws Exception {
        List<Map<String, Object>> fields = new ArrayList<>();
        try (Connection connection = dataSource.getConnection();
             ResultSet rs = connection.getMetaData().getColumns(null, null, tableName, null)) {

            while (rs.next()) {
                String columnName = rs.getString("COLUMN_NAME");
                if (FILTER_FIELDS.contains(columnName)) {
                    continue;
                }

                Map<String, Object> fieldInfo = buildFieldInfo(rs, columnName);
                fields.add(fieldInfo);
            }
        }
        return fields;
    }

    private Map<String, Object> buildFieldInfo(ResultSet rs, String columnName) throws Exception {
        Map<String, Object> fieldInfo = new LinkedHashMap<>();
        String dbType = rs.getString("TYPE_NAME");

        fieldInfo.put("value", columnName);
        fieldInfo.put("dbType", dbType);
        String remarks = rs.getString("REMARKS");
        fieldInfo.put("text", remarks);

        List<DictModel> dictItems = sysDictService.getDictItems(columnName);
        if (CollUtil.isNotEmpty(dictItems)) {
            fieldInfo.put("type", "select");
            fieldInfo.put("dictCode", columnName);
            fieldInfo.put("options", dictItems);
        } else {
            fieldInfo.put("type", mapDbTypeToFieldType(dbType));
        }

        return fieldInfo;
    }

    /**
     * 高级查询
     *
     * @param pageNo
     * @param pageSize
     * @param sysAdvancedQueryComponent
     * @param req
     * @return Result<IPage < SysAdvancedQueryComponent>>
     */
    @GetMapping(value = "/list")
    public Result<IPage<SysAdvancedQueryComponent>> list(
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            SysAdvancedQueryComponent sysAdvancedQueryComponent,
            HttpServletRequest req) {
        log.info("sysAdvancedQueryComponent的值：{}", JSON.toJSONString(sysAdvancedQueryComponent));
        log.info("req.getParameterMap()的值：{}", JSON.toJSONString(req.getParameterMap()));

        //封装通用查询
        QueryWrapper<SysAdvancedQueryComponent> queryWrapper = QueryGenerator.initQueryWrapper(sysAdvancedQueryComponent, req.getParameterMap());
        Page<SysAdvancedQueryComponent> page = new Page<SysAdvancedQueryComponent>(pageNo, pageSize);
        IPage<SysAdvancedQueryComponent> pageList = sysAdvancedQueryComponentService.page(page, queryWrapper);
        pageList.getRecords().forEach(
                sysAdvancedQueryComponent1 -> {
                    switch (sysAdvancedQueryComponent1.getField5()) {
                        case "1":
                            sysAdvancedQueryComponent1.setField5("男");
                            break;
                        case "2":
                            sysAdvancedQueryComponent1.setField5("女");
                            break;
                        default:
                            sysAdvancedQueryComponent1.setField5("未知");
                            break;
                    }
                }
        );
        return Result.OK(pageList);
    }

    @GetMapping(value = "/{id}")
    public ResponseEntity<SysAdvancedQueryComponent> getById(@PathVariable("id") String id) {
        return new ResponseEntity<>(sysAdvancedQueryComponentService.getById(id), HttpStatus.OK);
    }

    @PostMapping(value = "/create")
    public ResponseEntity<Object> create(@RequestBody SysAdvancedQueryComponent params) {
        sysAdvancedQueryComponentService.save(params);
        return new ResponseEntity<>("created successfully", HttpStatus.OK);
    }

    @PostMapping(value = "/delete/{id}")
    public ResponseEntity<Object> delete(@PathVariable("id") String id) {
        sysAdvancedQueryComponentService.removeById(id);
        return new ResponseEntity<>("deleted successfully", HttpStatus.OK);
    }

    @PostMapping(value = "/update")
    public ResponseEntity<Object> update(@RequestBody SysAdvancedQueryComponent params) {
        sysAdvancedQueryComponentService.updateById(params);
        return new ResponseEntity<>("updated successfully", HttpStatus.OK);
    }
}
